using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace XnaGameComponents
{
    public class GameConfiguration : IGameConfiguration
    {
        public GameConfiguration()
            : this(true)
        {
        }

        public GameConfiguration(bool initialize)
        {
            controls = new Collection<KeyAssociation>();
            if (initialize && !initializing)
                Initialize();
        }

        public static GameConfiguration LoadConfiguration(string path)
        {
            initializing = true;
            XmlSerializer serializer = new XmlSerializer(typeof(GameConfiguration));
            FileStream f = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            try
            {
                GameConfiguration config = (GameConfiguration)serializer.Deserialize(f);
                initializing = false;
                f.Close();
                return config;
            }
            catch
            {
                f.Close();
                return new GameConfiguration(false);
            }
        }

        private Collection<KeyAssociation> controls;
        private static bool initializing;

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public Collection<KeyAssociation> Controls
        {
            get { return controls; }
            set { controls = value; }
        }

        public void Initialize()
        {
            try
            {
                GameConfiguration config = LoadConfiguration("./game.config");
                foreach (KeyAssociation ka in config.Controls)
                    this[ka.Id] = ka.Key;
                Save();
            }
            catch { }
        }

        private void Save()
        {
            XmlSerializer serializer = new XmlSerializer(typeof(GameConfiguration));
            FileStream f = new FileStream("./game.config", FileMode.Truncate);
            try
            {
                serializer.Serialize(f, this);
            }
            finally
            {
                f.Close();
            }
        }

        #region IGameConfiguration Membres


        public Keys this[string id]
        {
            get
            {
                foreach (KeyAssociation ka in controls)
                {
                    if (ka.Id == id)
                        return ka.Key;
                }
                throw new KeyNotFoundException(id);
            }
            set
            {
                bool changed = false;
                foreach (KeyAssociation ka in controls)
                {
                    if (ka.Id == id)
                    {
                        ka.Key = value;
                        changed = true;
                        break;
                    }
                }
                if (!changed)
                    controls.Add(new KeyAssociation(id, value));
            }
        }
        #endregion
    }

    public class KeyAssociation
    {
        public KeyAssociation() { }
        public KeyAssociation(string id, Keys key)
        {
            this.id = id;
            this.key = key;
        }

        private string id;

        public string Id
        {
            get { return id; }
            set { id = value; }
        }

        private Keys key;

        public Keys Key
        {
            get { return key; }
            set { key = value; }
        }

        public override string ToString()
        {
            return id;
        }
    }
}
